﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using LiSAClient.Core.Messages;
using LiSAClient.Core.Viewmodel;

namespace LiSAClient.WpfClient.ViewModel.Frame.Menus
{
    public class MenuItemBase : ContentViewModel
    {
    protected Guid ID { get; set; }

        public bool IsSelectable { get; set; }

        /// <summary>
        /// The event that a closing request has been send.
        /// </summary>
        public event EventHandler ActivatedEvent;

        /// <summary>
        /// Notifies the listeners to <see cref="ActivatedEvent"/>.
        /// </summary>
        protected void OnActivated()
        {
            if (this.ActivatedEvent != null)
            {
                this.ActivatedEvent(this, EventArgs.Empty);
            }
        }

        public event EventHandler ChildActivatedEvent;

        /// <summary>
        /// Notifies the listeners to <see cref="ChildActivatedEvent"/>.
        /// </summary>
        protected void OnChildActivated()
        {
            if (this.ChildActivatedEvent != null)
            {
                this.ChildActivatedEvent(this, EventArgs.Empty);
            }
        }

        public IMenuHandler MenuHandler { get; set; }

        private bool isActivated;

        public bool IsActivated
        {
            get
            {
                return this.isActivated;
            }

            set
            {
                this.Set(() => this.IsActivated, ref this.isActivated, value);
            }
        }

        public ICommand ActivateMenuCommmand { get; set; }

        public bool IsContentVisible { get; set; }

        private bool isVisible;

        public bool IsVisible
        {
            get
            {
                return this.isVisible;
            }

            set
            {
                var old = this.isVisible;
                this.isVisible = value;
                if (old != this.isVisible)
                {
                    this.RaisePropertyChanged("CanDeleteButtonVisibility");
                }
            }
        }

        public string DisplayName { get; set; }

        public MenuItemBase Parent { get; set; }

        public ObservableCollection<MenuItemBase> Children { get; set; }

        protected MenuItemBase(IMenuHandler menuHandler)
        {
            this.IsSelectable = true;
            this.ID = Guid.NewGuid();
            this.MenuHandler = menuHandler;
            this.ActivateMenuCommmand = new RelayCommand(this.ActivateMenuAction);
            this.Children = new ObservableCollection<MenuItemBase>();
            Messenger.Default.Register<MenuItemActivatedMessage>(this, this.Handle);
            this.IsVisible = true;
        }

        private void Handle(MenuItemActivatedMessage obj)
        {
            if (obj.ActivatedMenuItemID != this.ID)
            {
                this.IsActivated = false;
            }
        }

        internal MenuItemBase Add(MenuItemBase item)
        {
            item.Parent = this;
            this.Children.Add(item);
            item.ActivatedEvent += this.ChildActivatedEventHandler;
            this.IsVisible = this.IsContentVisible || this.Children.Any(x => x.IsVisible);
            return this;
        }

        protected void ChildActivatedEventHandler(object sender, EventArgs eventArgs)
        {
            this.OnChildActivated();
            this.IsActivated = true;
            if (this.Parent != null)
            {
                this.Parent.OnChildActivated();
            }
        }

        public virtual void ActivateMenuAction()
        {
            if (IsSelectable)
            {
                Messenger.Default.Send(new MenuItemActivatedMessage { ActivatedMenuItemID = this.ID });
            }
            this.OnActivated();
            this.IsActivated = true;
        }
    }
}
